// 定义缓存空间名称
const version = "version39"; //修改此值可以强制更新缓存

// 定义需要缓存的文件目录
const fileList = [
  '/',
  '/index.html',
  "/main.js",
  "/main.css",
  "/images/book-192.png"
];

// 监听install事件，回调中缓存所需文件
self.addEventListener("install", (e) => {
  console.log("Service Worker 状态： install");
  this.skipWaiting(); // 强制更新sw.js
  e.waitUntil(
    // cacheStorage API 可直接用caches来替代
    // open方法创建/打开缓存空间，并会返回promise实例
    // then来接收返回的cache对象索引
    caches.open(version).then(function (cache) {
      // cache对象addAll方法解析（同fetch）并缓存所有的文件
      return cache.addAll(fileList);
    })
  );
});

// 拦截所有请求事件
// 如果缓存中已经有数据就直接用缓存，否则去请求数据
self.addEventListener("fetch", (e) => {
  // console.log("处理fetch事件:", e.request.url);
  // 判断版本是否已经切换，版本切换则资源前置走缓存
  e.respondWith(
    caches
      .match(e.request)
      .then(async function (response) {
        // 是否版本改变，是则之前取远程资源
        let verData = {
          version: version
        };
        try {
          verData =  await fetch('./version.json?v='+new Date()).then((res)=>{
          if(res.status == 200){
              return res.json();
          }else {
              return {}
          }
          }).then(data => { return data;}); 
        }catch (e) {}
        console.log("response:",  e.request.url);
        if(version  !=  verData.version){
          console.log("根据版本强制获取最新资源",  e.request.url, caches);
          return fetch(e.request);
        } else {
          if (response) {
            console.log("缓存匹配到res:",  e.request.url,response);
            return response;
          }
          console.log("缓存未匹配对应request,准备从network获取",  e.request.url,caches);
          return fetch(e.request);
        }
       
       
      })
      .catch((err) => {
        console.error(err);
        return fetch(e.request);
      })
  );
});

// // 监听active事件
self.addEventListener("activate", (event) => {
  console.log("Service Worker 状态： activate");
  // 获取所有的缓存key值，将需要被缓存的路径加载放到缓存空间下
  const cacheDeletePromise = caches.keys().then((keyList) => {
    console.log("keyList:", keyList);
    Promise.all(
      keyList.map((key) => {
        if (key !== version) {
          const deletePromise = caches.delete(key);
          //告诉用户需要重新刷新
          console.log("need reload");
          self.clients.matchAll().then(function (clients) {
            clients.forEach(function (client) {
              client.postMessage({
                command: "reload",
                message: "test",
              });
            });
          });
          return deletePromise;
        } else {
          Promise.resolve();
        }
      })
    );
  });
  // 等待所有的缓存都被清除后，直接启动新的缓存机制
  event.waitUntil(
    Promise.all([cacheDeletePromise]).then((res) => {
      this.clients.claim();
    })
  );
});

// 取消注册：先删除所有缓存，删除再取消注册

// 如何实现桌面图标
// 如何实现实时更新
// 如何实现离线访问

// 实现方案：（1）第一次进去还是旧的文件，发现有更新后，加弹窗用户刷新（或者直接强制刷新）
//          （2）通过本地构建一个版本号文件，如果版本号改变，则走网络请求，否则走本地缓存
//          （3）通过地址栏上url带上版本信息，确定是否走缓存。
